package net.sk.china.platform.service.impl.order;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import net.sk.china.platform.service.order.LogisticService;
import net.sk.china.platform.service.system.SystemConfigService;
import net.sk.china.common.constants.Constants;
import net.sk.china.common.exception.TalkException;
import net.sk.china.common.utils.RedisUtil;
import net.sk.china.common.utils.RestTemplateUtil;
import net.sk.china.common.vo.LogisticsResultVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;


/**
* ExpressServiceImpl 接口实现
*  +----------------------------------------------------------------------
 *  | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2018-2024 聊来All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 *  +----------------------------------------------------------------------
 *  | @Author: 聊来 <18970881148@qq.com>
 *  +----------------------------------------------------------------------
*/

@Data
@Service
public class LogisticsServiceImpl implements LogisticService {

    private final SystemConfigService systemConfigService;

    private final RestTemplateUtil restTemplateUtil;

    private final RedisUtil redisUtil;

    private String redisKey = Constants.LOGISTICS_KEY;
    private Long redisCacheSeconds = 1800L;

    private String expressNo;

    public LogisticsServiceImpl(SystemConfigService systemConfigService, RestTemplateUtil restTemplateUtil, RedisUtil redisUtil) {
        this.systemConfigService = systemConfigService;
        this.restTemplateUtil = restTemplateUtil;
        this.redisUtil = redisUtil;
    }


    /** 快递
     * @param expressNo String 物流单号
     * @param type String 快递公司字母简写：不知道可不填 95%能自动识别，填写查询速度会更快 https://market.aliyun.com/products/56928004/cmapi021863.html#sku=yuncode15863000015
     * @param com 快递公司编号
     * @return {@code LogisticsResultVo}
     */
    @Override
    public LogisticsResultVo info(String expressNo, String type, String com, String phone) {
        setExpressNo(expressNo);
        JSONObject result = getCache();
        if (ObjectUtil.isNotNull(result)) {
            return JSONObject.toJavaObject(result, LogisticsResultVo.class);
        }
        String appCode = systemConfigService.getValueByKey(Constants.CONFIG_KEY_LOGISTICS_APP_CODE);

        // 顺丰请输入单号 : 收件人或寄件人手机号后四位。例如：123456789:1234
        if (StrUtil.isNotBlank(com) && com.equals("shunfengkuaiyun")) {
            expressNo = expressNo.concat(":").concat(StrUtil.sub(phone, 7, -1));
        }
        String url = Constants.LOGISTICS_API_URL + "?no=" + expressNo;
        if(StringUtils.isNotBlank(type)){
            url += "&type=" + type;
        }

        HashMap<String, String> header = new HashMap<>(2);
        header.put("Authorization", "APPCODE " + appCode);

        JSONObject data = restTemplateUtil.getData(url, header);
        checkResult(data);
        //把数据解析成对象返回到前端
        result = data.getJSONObject("result");
        saveCache(result);
        LogisticsResultVo resultVo = JSONObject.toJavaObject(result, LogisticsResultVo.class);

        return resultVo;
    }

    /** 获取快递缓存
     * @return {@code JSONObject}
     */
    private JSONObject getCache() {
        Object data = redisUtil.get(getRedisKey() + getExpressNo());
        if(null != data){
         return JSONObject.parseObject(data.toString());
        }
        return null;
    }

    /** 获取快递缓存
     * @param data JSONObject 需要保存的数据
     */
    private void saveCache(JSONObject data) {
        redisUtil.set(getRedisKey() + getExpressNo(), data.toJSONString(), getRedisCacheSeconds(), TimeUnit.SECONDS);
    }

    /** 获取快递缓存
     * @param data JSONObject 检测返回的结果
     */
    private void checkResult(JSONObject data) {
        if (!data.getString("status").equals("0")){
            throw new TalkException(data.getString("msg"));
        }
    }
}

